﻿namespace ConsoleApp1
{
    /// <summary>
    /// 从状态机的角度async和await的实现原理(新)
    /// <para>https://www.cnblogs.com/yaopengfei/p/12848795.html</para>
    /// </summary>
    internal class Task1
    {
        /// <summary>
        /// 该方法为主方法,用于调用下面的F1-F5的方法
        /// </summary>
        /// <returns></returns>
        public async Task IndexAsync()
        {
            await F1Async();
            await F2Async();
            await F3Async();
            await F4Async();
            await F5Async();
        }

        /// <summary>
        /// 没有加async和await的方法
        /// (也是一个计算密集型的异步方法,只是编译的时候本身不会被编译成状态机)
        /// </summary>
        /// <returns></returns>
        public static Task<int> F1Async()
        {
            return Task.Run(() =>
            {
                return 2;
            });
        }

        /// <summary>
        /// 只要标记了async 就会被编译成状态机
        /// 如果方法声明为 async，那么可以直接 return 具体的值，不再用创建Task，由编译器创建 Task： 
        /// </summary>
        /// <returns></returns>
        public static async Task<int> F2Async()
        {
            return 2;
        }

        /// <summary>
        /// 计算密集型的异步方法
        /// (方法本身也会被编译成状态机)
        /// </summary>
        /// <returns></returns>
        public static async Task<int> F3Async()
        {
            return await Task.Run(() =>
            {
                return 2;
            });
        }

        /// <summary>
        /// I/O密集型的异步方法
        /// </summary>
        /// <returns></returns>
        public async Task<int> F4Async()
        {
            var path = "../../txt/1.txt";
            for (int i = 0; i < 10000; i++)
            {
                await File.WriteAllTextAsync(path, i.ToString());
            }

            var str = await File.ReadAllTextAsync(path);
            return str.Length;
        }


        /// <summary>
        /// 没有创建状态机，但是new 了1个新的 task
        /// </summary>
        /// <returns></returns>
        public static Task<int> F5Async()
        {
            //内部是new Task<TResult>(result)
            return Task.FromResult(3);
        }
    }
}
